#include "array.h"
 
#include "utils.h"

void convert(Array<int>& dst, const Array<char>& src){
    int i = 0;
    int size = dst.size() < src.size() ? dst.size() : src.size();
    while (i < size){
        dst[i] = src[i] >= '0' && src[i] <= '9' ? (int)src[i] - '0' : -1;
        i++;
    }
    Utils::fill(dst, size, 0, dst.size() - size);
}
 

#include "ptr_array.h"
#include "dynamic_array.h"
#include "static_array.h"
#include "resizable_array.h"

 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

 
typedef StaticArray<int, 3> Array3;

void print(const Array<int>& a, const char name[]){
    for (int i = 0; i < a.size(); i++){
        printf("%s[%d]=%d\t", name, i, a[i]);
    }
    printf("\n");
}

void print(const Array< StaticArray<int, 3> >& a, const char name[]){
    StaticArray<char, 100> name2;
    int len = strlen(name);
    Utils::move(name2, 0, name, len);
    name2[len] = '[';
    len++;
    for (int i = 0; i < a.size(); i++){
        char ind = i + '0';
        int indlen = 1;
        Utils::move(name2, len, &ind, indlen);
        name2[len+indlen] = ']';
        name2[len+indlen+1] = '\0';
        print(a[i], &name2[0]);
    }
    printf("\n");
}


int main(int argc, char* argv[]){
    ResizableArray<int> ra;
    int A1[] = {1, 2, 3, 4};
    int A2[] = {5, 6, 7, 8, 9};
    int A3[] = {-1, -2, -3, -4, -5, -6};

    ra.append(A1, 4);
    ra.append(A2, 5);
    ra.append(A3, 6);

    StaticArray<int, 15> temp(ra);

    ra.remove(1, 13);
    print(ra, "rr");
    ra = temp;

    PtrArray<int> pa(4, A1, false);
    print(pa, "pa");
   
    pa.valid();
 
//    ra.append(StaticArray<int, 4>(A1));
//    ra.append(StaticArray<int, 5>(A2));
//    ra.append(StaticArray<int, 6>(A3));

    ra = Utils::merge(ra, StaticArray<int, 4>(A1));
    ra = Utils::merge(ra, StaticArray<int, 5>(A2));
    ra = Utils::merge(ra, StaticArray<int, 6>(A3));

    ra.append(DynamicArray<int>(4, A1));
    ra.append(DynamicArray<int>(5, A2));
    ra.append(DynamicArray<int>(6, A3));

    ra.append(ra);
    ra.insert(0, ra);

    printf("size=%d, capacity=%d \n", ra.size(), ra.capacity());

    const int SZ = ((4+5+6)*3) * 2 * 2;

    printf("the size must be %d \n", SZ);

    print(ra, "r");

    printf("\n");
    StaticArray<int, SZ> sa(ra);

    print(sa, "s");
}

int main2(int argc, char* argv[]){
    DynamicArray<int> da(5);
    StaticArray<int, 5> sa;

    Utils::move(sa, da);
    Utils::move(da, sa);

    sa = da;

//    da = sa;

}



int main3(int argc, char* argv[]){
    StaticArray<int, 0> a0;

    StaticArray<int, 5> a1, a2;
    StaticArray<int, 10> b1, b2;
    StaticArray<char, 30> c1;
    DynamicArray<int> d(20);

//  d1 = a1;
    
    a1[0] = 1;
    a1[1] = 2;
    a1[2] = 3;
    a1[3] = 4;
    a1[4] = 5;

    DynamicArray<int> d1(a1);

//    move(d1, a1);

//    d1 = a1;
    int z;


    print(a1, "a1");
    print(d1, "d1");

    printf("\n");

    d1[1] = d1[1]*10;
 
    a1 = a1;


    a1 = d1;
    d1 = a1;

    print(a1, "a1");
    print(d1, "d1");

    DynamicArray<Array3> DA(2);
    StaticArray<Array3, 2> SA;

//  DA = DA;
    
    const int n = 15;

    StaticArray<int, n> an;

    SA[1][2] = 123;

    print(DA, "DA");
    print(SA, "SA");

    SA = SA;

    print(DA, "DA");
    print(SA, "SA");


    Utils::move(c1, 0, "Hello", 6);
    printf("%s\n", &c1[0]);

    Utils::move(a1, a2);
    Utils::move(b1, b2);
    Utils::move(b2, a2);
 
    Utils::merge(an, a1, b2);

    DynamicArray<int> bn(an.size(), &an[0]);

    for (int k = 0; k < bn.size(); k++){
        if (an[k] != bn[k]){
            printf("error in %d \n", k);
        }
    }

    int x, y;

    for (x = 0; x < SA.size(); x++){
        for (y = 0; y < SA[x].size(); y++){
            SA[x][y] = x * 100 + y;
        }
    }


    print(SA, "SA");

//  move(DA, SA);

//  Array<Array3> AA;
//  printf("%d \n", AA.size);

//  DA = AA;

//    SA = SA;
//    DA = DA;
//    SA = DA;
    DA = SA;

    print(SA, "SA");
    print(DA, "DA");
/*
    Array3 h = DA[0];
    DA[0] = DA[1];
    DA[1] = h;

    print(SA, "SA");
    print(DA, "DA");

    SA = DA;

    print(SA, "SA");
    print(DA, "DA");
*/

    printf("size_0=%d, size_1=%d \n", SA.size(), SA[0].size());

    for (x = 0; x < SA.size(); x++){
        for (y = 0; y < SA[x].size(); y++){
            printf("[%d, %d] = %d \t", x, y, SA[x][y]);
            if (DA[x][y] != x * 100 + y){
                printf("error in %d, %d \n", x, y);
            }
        }
        printf("\n");
    }

    DA[0] = SA[0];

    Utils::move(DA[0], SA[0]);

    Utils::merge(bn, a1, b2);

    a1[3] = b2[5];
 
    convert(a1, c1);

    Utils::merge(d, a1, b1);

    for (int j = 0; j < 5; j++){
        a1[j] = j;
        a2[j] = j + 5;
    }
    Utils::merge(b1, a1, a2);
    Utils::merge(d, b1, b1);
 
    for (int i = 0; i < 10; i++){
        if (d[i] != i || d[i+10] != i){
            printf("error in %d \n", i);
        }
    }
    return 0;
}



